package com.risenetsoft.elasticsearch.api;

import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.get.GetField;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryAction;
import org.elasticsearch.script.Script;
import org.elasticsearch.transport.client.PreBuiltTransportClient;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

/**
 * Created by Zhanggd on 2017/8/7.
 */
public class ElkTest {
    public static final String CLUSTER_NAME = "elasticsearch"; //实例名称
    private static final String IP = "192.168.190.104";
    //private static final String IP = "192.168.190.101";
    private static final int PORT = 9300;  //端口

    //1.设置集群名称：默认是elasticsearch，并设置client.transport.sniff为true，
    // 使客户端嗅探整个集群状态，把集群中的其他机器IP加入到客户端中
    private static Settings settings = Settings.builder()
            .put("cluster.name", CLUSTER_NAME)
            .put("client.transport.sniff",true)
            .put("client.transport.ping_timeout","120s")//解决GC运行响应慢而引起ReceiveTimeoutTransportException
            .build();
    //创建私有对象
    private static TransportClient client;

    //创建单例的TransportClient对象
    static {
        try {
            client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(IP), PORT));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    //取得实例
    public static synchronized TransportClient getTransportClient(){
        return client;
    }

    //为集群添加新的节点
    public static synchronized void addNode(String name,Integer port){
        try {
            client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(name),port));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    //删除集群中的某个节点
    public static synchronized void removeNode(String name,Integer port){
        try {
            client.removeTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(name),port));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        //insertDoc();

        //insertJson();

        //getES();

        //deleteById();

        //prepareUpdate();

    }

    /**
     * 以下示例将JSON文档索引到名为twitter的索引中，名为tweet，其值为1：
     */
    public static void insertDoc(){
        try {
            IndexResponse response = client.prepareIndex("twitter", "tweet", "1")
                    .setSource(jsonBuilder()
                                    .startObject()
                                    .field("user", "kimchy")
                                    .field("postDate", new Date())
                                    .field("message", "trying out Elasticsearch")
                                    .endObject()
                    )
                    .get();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void insertJson(){
        String json = "{" +
                "\"user\":\"kimchy\"," +
                "\"postDate\":\"2013-01-30\"," +
                "\"message\":\"trying out Elasticsearch\"" +
                "}";
        IndexResponse response = client.prepareIndex("twitter","tweet")
                .setSource(json)
                .get();
    }

    /**
     * 从twitter的索引获取一个JSON文档，名为tweet，其值为1
     */
    public static void getES(){
        GetResponse response = client.prepareGet("twitter", "tweet", "1")
                .setOperationThreaded(false)
                .get();
        //获取字段
        Map<String, GetField> fieldMap = response.getFields();
        for(Map.Entry<String,GetField> entry:fieldMap.entrySet()){
            String key = entry.getKey();
            GetField field = entry.getValue();

            String fieldName = field.getName();
            List<Object> values = field.getValues();

            System.out.println("字段名称:"+fieldName+",字段值："+values);
        }

    }

    public static void deleteById(){
        DeleteResponse response = client.prepareDelete("twitter", "tweet", "1")
                .get();
    }

    public static void deleteByQuery(){
        BulkByScrollResponse response = DeleteByQueryAction.INSTANCE
                .newRequestBuilder(client)
                .filter(QueryBuilders.matchQuery("gender","male"))
                .source("persions")
                .get();
    }

    public static void updateRequest() throws IOException {
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("index");
        updateRequest.type("type");
        updateRequest.id("1");
        updateRequest.doc(jsonBuilder()
                .startObject()
                .field("gender","male")
                .endObject()
        );
        client.update(updateRequest);
    }

    public static void prepareUpdate() throws IOException {
/*        UpdateResponse updateResponse = client.prepareUpdate("ttl", "doc", "1")
                .setScript(new Script("ctx._source.gender = \"male\"", ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING, null, null))
                .get();*/

        client.prepareUpdate("twitter", "tweet", "1")
                .setDoc(jsonBuilder()
                        .startObject()
                        .field("user", "zhangsanfeng")
                        .endObject())
                .get();
    }

    /**
     * 根据提供的脚本去更新文档
     */
    public static void updateByScript(){

        try {
            UpdateRequest updateRequest = new UpdateRequest("ttl", "doc", "1")
                    .script(new Script("ctx._source.gender = \"male\""));
            client.update(updateRequest).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

    }

    /**
     * 通过合并更新文档
     */
    public static void updateByMerge(){
        try {
            UpdateRequest updateRequest = new UpdateRequest("index","type","1")
                    .doc(jsonBuilder()
                    .startObject()
                    .field("gender", "male")
                    .endObject());
            client.update(updateRequest).get();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public static void updateUpsert(){
        try {
            IndexRequest indexRequest = new IndexRequest("index", "type", "1")
                    .source(jsonBuilder()
                            .startObject()
                            .field("name", "Joe Smith")
                            .field("gender", "male")
                            .endObject());
            UpdateRequest updateRequest = new UpdateRequest("index", "type", "1")
                    .doc(jsonBuilder()
                    .startObject()
                    .field("gender", "male")
                    .endObject())
                    .upsert(indexRequest);
            client.update(updateRequest).get();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}
